package com.gebogebo.mobile.parking.calculator;

import com.gebogebo.mobile.parking.model.SearchArea;

public class GeoDistanceHelper {

	public static final Double earthRadius = 1000D ; // in KM
	/**
	 * @param radius radius of the sphere.
	 * @param location center of the query circle.
	 * @param distance radius of the query circle.
	 * @param connection an SQL connection.
	 * @return places within the specified distance from location.
	 */
	public static String findPlacesWithinDistance(SearchArea area ) {

		GeoLocation location = GeoLocation.fromRadians(area.getLatitude(), area.getLongitude());
		double distance = area.getRadius();
		double radius = earthRadius;
		GeoLocation[] boundingCoordinates =
			location.boundingCoordinates(distance, radius);
		boolean meridian180WithinDistance =
			boundingCoordinates[0].getLongitudeInRadians() >
			boundingCoordinates[1].getLongitudeInRadians();

		String query ="";
		
		if(meridian180WithinDistance) {
			query = String.format("SELECT * FROM parking_spots WHERE (latitude >= %s AND latitude <= %s) AND (longitude >= %s OR longitude <= %s) AND  acos(sin(%s) * sin(latitude) + cos(%s) * cos(latitude) * cos(longitude - %s)) <= %s", 
					boundingCoordinates[0].getLatitudeInRadians(), boundingCoordinates[1].getLatitudeInRadians(),boundingCoordinates[0].getLongitudeInRadians(), boundingCoordinates[1].getLongitudeInRadians(), location.getLatitudeInRadians(), location.getLatitudeInRadians(), location.getLongitudeInRadians(), distance / radius);
			
		}
		else {
			query = String.format("SELECT * FROM parking_spots WHERE (latitude >= %s AND latitude <= %s) AND (longitude >= %s AND longitude <= %s) AND  acos(sin(%s) * sin(latitude) + cos(%s) * cos(latitude) * cos(longitude - %s)) <= %s", 
					boundingCoordinates[0].getLatitudeInRadians(), boundingCoordinates[1].getLatitudeInRadians(),boundingCoordinates[0].getLongitudeInRadians(), boundingCoordinates[1].getLongitudeInRadians(), location.getLatitudeInRadians(), location.getLatitudeInRadians(), location.getLongitudeInRadians(), distance / radius);
			
		}

		return query;
	}
}
